/*
   Copyright 2009 Bloo. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package org.youtensils.www.client.widgets;

import org.youtensils.www.client.resources.GlobalImages;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;

/**
 * A widget providing download tracking features.
 * @author Bobby Soares
 */
public class DownloadTracker extends Composite implements ClickHandler {
	
	public static final String QUEUED_STATUS = "Queued";
	public static final String ACTIVE_STATUS = "Active";
	public static final String ERROR_STATUS = "Error";
	public static final String COMPLETED_STATUS = "Completed";
	public static final String STARTING_STATUS = "Starting";
	public static final String CANCELED_STATUS = "Canceled";
	
	private DownloadManager manager;
	private String downloadId;
	private Image closeButton;
	private Anchor upButton, downButton;
	private HorizontalPanel mainPanel;
	private Label statusLabel, formatLabel, nameLabel, loadedLabel, totalLabel, actionLabel;
	private ProgressBar progressBar;
    /**
     * A constructor specifying the download id and the parent DownloadManager
     * @param downloadId the id of the download to be tracked
     * @param manager the parent download manager to which this tracker belongs
     */
    public DownloadTracker(String downloadId, DownloadManager manager) {
    	this.downloadId = downloadId;
    	this.manager = manager;
    	mainPanel = new HorizontalPanel();
    	mainPanel.setWidth("100%");
    	mainPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
    	
    	closeButton = GlobalImages.images.CloseGeneric().createImage();
    	closeButton.setStyleName("gwt-DownloadTracker-CloseButton");
    	closeButton.addClickHandler(this);
    	upButton = new Anchor();
    	upButton.setText("Up");
    	upButton.addClickHandler(this);
    	downButton = new Anchor();
    	downButton.setText("Down");
    	downButton.addClickHandler(this);
    	
    	progressBar = new ProgressBar();
    	progressBar.setWidth("200px");
    	progressBar.setHeight("10px");
    	
    	statusLabel = new Label();
    	statusLabel.setWidth("60px");
    	statusLabel.setStyleName("gwt-DownloadTracker-Label");
    	formatLabel = new Label();
    	formatLabel.setWidth("50px");
    	formatLabel.setStyleName("gwt-DownloadTracker-Label");
    	nameLabel = new Label();
    	nameLabel.setWidth("300px");
    	nameLabel.setStyleName("gwt-DownloadTracker-Label");
    	loadedLabel = new Label();
    	loadedLabel.setWidth("60px");
    	loadedLabel.setStyleName("gwt-DownloadTracker-Label");
		totalLabel = new Label();
		totalLabel.setWidth("60px");
		totalLabel.setStyleName("gwt-DownloadTracker-Label");
		actionLabel = new Label();
		actionLabel.setWidth("100px");
		actionLabel.setStyleName("gwt-DownloadTracker-Label");
    	
		mainPanel.add(closeButton);
		mainPanel.add(upButton);
		mainPanel.add(downButton);
		mainPanel.add(statusLabel);
		mainPanel.add(formatLabel);
		mainPanel.add(nameLabel);
		mainPanel.add(progressBar);
		mainPanel.add(loadedLabel);
		mainPanel.add(totalLabel);
		mainPanel.add(actionLabel);
		mainPanel.add(new Label());
    	
    	initWidget(mainPanel);
    	setStyleName("gwt-DownloadTracker");
    }
    
	@Override
	public void onClick(ClickEvent event) {
		Object sender = event.getSource();
    	if (sender == this.upButton) {
    		this.manager.increaseDownloadPriority(this);
    	}else if(sender == this.downButton){
    		this.manager.decreaseDownloadPriority(this);
    	}else if(sender == this.closeButton){
    		boolean ok = true;
    		int per = this.getProgress();
    		String status = this.getProgressStatus();
    		if (status.equals(ACTIVE_STATUS) ||
    			status.equals(STARTING_STATUS)) {
	    		if(per > 0 && per < 100){
	    			ok = confirm("You have selected to cancel an active download. You'll not be able to undo this.");
	    		}
	    		if(ok){
	    			this.manager.cancelDownload(this.downloadId);
	    		}
    		} else {
    			this.manager.removeDownload(this.downloadId);
    		}
    	}
	}
	
    /**
     * Updates the progress information for this download.
	 * @param percentage a percentage value indicating how close to completion the download is
     * @param status the status of the download
     * @param format the format of the download
     * @param name the name of the download
	 * @param loaded the number of bytes that have loaded for this download
	 * @param total the total number of bytes for this download
	 * @param action a value describing the current action
     */
    public void setProgressInformation(int percentage, String status, String format,
    			String name, String loaded, String total, String action){
    	if(name.length() > 50) name = name.substring(0, 50) + "...";
    	this.setProgress(percentage);
    	this.setProgressStatus(status);
    	this.setDownloadFormat(format);
    	this.setDownloadName(name);
    	this.setProgressLoaded(loaded);
    	this.setProgressTotal(total);
    	this.setProgressAction(action);
    }
    /**
     * Sets the progress percentage for the tracked download.
     * @param percentage the progress percentage
     */
    public void setProgress(int percentage){
    	this.progressBar.setProgress(percentage);
    }
    /**
     * Retrieves the progress percentage for the tracked download.
     * @return the progress percentage
     */
    public int getProgress(){
    	return this.progressBar.getProgress();
    }
    /**
     * Sets the progress status for the tracked download.
     * @param value the progress status
     */
    public void setProgressStatus(String value){
    	this.statusLabel.setText(value);
    }
    /**
     * Retrieves the progress status for the tracked download.
     * @return the progress status
     */
    public String getProgressStatus(){
    	return this.statusLabel.getText();
    }
    /**
     * Sets the format for the tracked download.
     * @param value the download format
     */
    public void setDownloadFormat(String value){
    	this.formatLabel.setText(value);
    }
    /**
     * Retrieves the download format for the tracked download.
     * @return the download format
     */
    public String getDownloadFormat(){
    	return this.formatLabel.getText();
    }
    /**
     * Sets the name for the tracked download.
     * @param value the download name
     */
    public void setDownloadName(String value){
    	this.nameLabel.setText(value);
    }
    /**
     * Retrieves the download name for the tracked download.
     * @return the download name
     */
    public String getDownloadName(){
    	return this.nameLabel.getText();
    }
    /**
     * Sets the number of bytes loaded for the tracked download.
     * @param value the number of bytes loaded
     */
    public void setProgressLoaded(String value){
    	this.loadedLabel.setText(value);
    }
    /**
     * Retrieves the number of bytes loaded for the tracked download.
     * @return the number of bytes loaded
     */
    public String getProgressLoaded(){
    	return this.loadedLabel.getText();
    }
    /**
     * Sets the total number of bytes for the tracked download.
     * @param value the total number of bytes
     */
    public void setProgressTotal(String value){
    	this.totalLabel.setText(value);
    }
    /**
     * Retrieves the total number of bytes for the tracked download.
     * @return the total number of bytes
     */
    public String getProgressTotal(){
    	return this.totalLabel.getText();
    }
    /**
     * Sets the action label for the tracked download.
     * @param value the action label
     */
    public void setProgressAction(String value){
    	this.actionLabel.setText(value);
    }
    /**
     * Retrieves the action label the tracked download.
     * @return the action label
     */
    public String getProgressAction(){
    	return this.actionLabel.getText();
    }
    /**
     * Retrieves the id of the tracked download.
     * @return the download id
     */
    public String getDownloadId() {
		return downloadId;
	}
	/**
	 * Wraps aroud the native JavaScript confirm function.
	 * @param msg the message to display in the confirm prompt
	 * @return a boolean indicating whether the user clicked OK or Cancel
	 */
	public native boolean confirm(String msg) /*-{
		return confirm(msg);
	}-*/;
	
}